package me.landery.modules.sinco.service.impl;

import lombok.RequiredArgsConstructor;
import me.landery.exception.BadRequestException;
import me.landery.modules.sinco.domain.Call;
import me.landery.modules.sinco.domain.Recharge;
import me.landery.modules.sinco.repository.RechargeRepository;
import me.landery.modules.sinco.service.RechargeService;
import me.landery.modules.sinco.service.VipService;
import me.landery.modules.sinco.service.dto.CallDto;
import me.landery.modules.sinco.service.dto.ReChargeQueryCriteria;
import me.landery.modules.sinco.service.dto.RechargeDto;
import me.landery.modules.sinco.service.dto.VipDto;
import me.landery.modules.sinco.service.mapstruct.RechargeMapper;
import me.landery.modules.sinco.service.mapstruct.VipMapper;
import me.landery.modules.system.domain.User;
import me.landery.utils.PageUtil;
import me.landery.utils.QueryHelp;
import me.landery.utils.RedisUtils;
import me.landery.utils.SecurityUtils;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.prefs.BackingStoreException;

/**
 * @Author cc.w
 * @Date 2022/6/7 16:55
 * @Version 1.0
 */
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "recharge")
public class RechargeServiceImpl implements RechargeService {

    private final RechargeRepository rechargeRepository;
    private final RechargeMapper rechargeMapper;
    private final RedisUtils redisUtils;

    private final VipService vipService;
    private final VipMapper vipMapper;

    @Override
    public Map<String, Object> queryAll(ReChargeQueryCriteria criteria, Pageable pageable) {
        Page<Recharge> page = rechargeRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(rechargeMapper::toDto).getContent(),page.getTotalElements());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(Recharge resources) {
        rechargeRepository.save(resources);
    }

    @Override
    public List<RechargeDto> findByUsersId(Long id) {
        return rechargeMapper.toDto(new ArrayList<>(rechargeRepository.findByUserId(id)));
    }

    /**
     * 处理支付宝充值返回成功return处理
     * @param outTradeNo 商户订单号
     * @param tradeNo 支付宝交易号
     */
    @Override
    public void paySuccess(String outTradeNo, String tradeNo) {
        //先去数据库拿订单
        Recharge recharge = rechargeRepository.findByOutTradeNo(outTradeNo);
//        //判断订单是否是同一个用户支付的
//        User user = recharge.getUser();
//        //获取当前登录用户ID
//        if(!Objects.equals(user.getId(), SecurityUtils.getCurrentUserId())){
//            throw new BadRequestException("用户信息错误，处理失败");
//        }


        if (recharge.getTradeNo() != null){
            recharge.setTradeNo(tradeNo);
            rechargeRepository.save(recharge);
        }



        //修改余额信息
        //获取当前用户的vip信息
//        VipDto vipDto = vipService.findByUserID(recharge.getUser().getId());
//        vipDto.setBalance(vipDto.getBalance() + recharge.getBalance());
//        vipService.save(vipMapper.toEntity(vipDto));

    }

    @Override
    @Transactional
    public void paySuccessAfterNotify(String outTradeNo, String tradeNo, String totalAmount) {
        //先去数据库拿订单
        Recharge recharge = rechargeRepository.findByOutTradeNo(outTradeNo);
//        //判断订单是否是同一个用户支付的
//        User user = recharge.getUser();
//        //获取当前登录用户ID
//        if(!Objects.equals(user.getId(), SecurityUtils.getCurrentUserId())){
//            throw new BadRequestException("用户信息错误，处理失败");
//        }
        //比较tradeNo 流水号、总价totalAmount
        if(recharge.getTradeNo() != null && !Objects.equals(recharge.getTradeNo(), tradeNo) ){
            throw new BadRequestException("流水号错误");
        }

        if (recharge.getBalance() != null && Math.abs(recharge.getBalance()-Double.parseDouble(totalAmount)) > 1e-6){
            throw new BadRequestException("总价错误");
        }

        //修改订单状态
        //先判断状态是否为1则转为4 否则就不改动
        if(recharge.getTradeNo()  == null){
            recharge.setTradeNo(tradeNo);
        }
        if (recharge.getRechargeState() == 2){ //等待确认
            recharge.setRechargeState(3);  //充值成功
            rechargeRepository.save(recharge);
            //修改余额信息
            //获取当前用户的vip信息
            VipDto vipDto = vipService.findByUserID(recharge.getUser().getId());
            vipDto.setBalance(vipDto.getBalance() + recharge.getBalance());
            vipService.save(vipMapper.toEntity(vipDto));
        }else{
            throw new BadRequestException("订单状态错误");
        }

    }

    /**
     * 支付失败
     * @param outTradeNo
     * @param tradeNo
     * @param totalAmount
     */
    @Override
    @Transactional
    public void payFailAfterNotify(String outTradeNo, String tradeNo, String totalAmount) {
        //先去数据库拿订单
        Recharge recharge = rechargeRepository.findByOutTradeNo(outTradeNo);
        //比较tradeNo 流水号、总价totalAmount

        if(recharge.getTradeNo() != null && !Objects.equals(recharge.getTradeNo(), tradeNo) ){
            throw new BadRequestException("流水号错误");
        }

        if (recharge.getBalance() != null && Math.abs(recharge.getBalance()-Double.parseDouble(totalAmount)) > 1e-6){
            throw new BadRequestException("总价错误");
        }

        //修改订单状态
        //先判断状态是否为2则转为1 否则就不改动
        if(recharge.getTradeNo()  == null){
            recharge.setTradeNo(tradeNo);
        }
        if (recharge.getRechargeState() == 2){ //等待确认
            recharge.setRechargeState(1);  //充值失败
            rechargeRepository.save(recharge);
        }else {
            throw new BadRequestException("订单状态错误");
        }
//        //修改余额信息
//        //获取当前用户的vip信息
//        VipDto vipDto = vipService.findByUserID(recharge.getUser().getId());
//        vipDto.setBalance(vipDto.getBalance() + recharge.getBalance());
//        vipService.save(vipMapper.toEntity(vipDto));

    }

    @Override
    public List<Recharge> findByUsersIdAndStatus(Long currentUserId, int i) {
        return rechargeRepository.findByUserIdAndRechargeState(currentUserId,i);
    }

    @Override
    public void update(Recharge recharge) {
        rechargeRepository.save(recharge);
    }


}
